package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.CodeInValidException;
import common.DBUtil;
import common.ProblemNotFoundException;
import compile.Answer;
import compile.Question;
import compile.Task;
import dao.Problem;
import dao.ProblemDAO;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

@WebServlet("/compile")
public class CompileServlet extends HttpServlet {

    static class CompileRequest{
        //题目的编号
        public int id;
        //用户的代码
        public String code;
    }

    static class CompileResponse{
        //错误类别。0为ok，1为编译错误，2为运行错误
        public int error;
        //错误原因
        public String reason;
        //运行结输出
        public String stdout;
    }

    private ObjectMapper mapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        CompileResponse response = new CompileResponse();
        CompileRequest request = null;
        try {
            resp.setStatus(200);
            resp.setContentType("application/json;charset=utf8");
            //1.先读取请求的正文，按照json格式进行解析
            String body = readBody(req);
            //2.根据id从数据库中查找题目的详情=》得到测试样例代码
            request = mapper.readValue(body, CompileRequest.class);
            ProblemDAO problemDAO = new ProblemDAO();
            Problem problem = problemDAO.selectOne(request.id);
            if (problem == null){
                throw new ProblemNotFoundException();
            }
            String testCode = problem.getTestCode();
            String requestCode = request.code;
            //3.把用户提交的代码和测试样例代码给拼接成一个完整的代码
            String finalCode = mergeCode(requestCode,testCode);
            if (finalCode == null){
                throw new CodeInValidException();
            }
            //4，创建一个Task实例，调用里面的compileAndRun来进行编译运行
            Task task = new Task();
            Question question = new Question();
            question.setCode(finalCode);
            Answer answer = task.compileAndRun(question);
            //5.根据Task运行的结果，包装成一个HTTP响应
            response.error = answer.getError();
            response.reason = answer.getReason();
            response.stdout = answer.getStdout();
        } catch (ProblemNotFoundException e) {
            response.error = 3;
            response.reason = "没有找到指定题目 id = " + request.id;
        } catch (CodeInValidException e) {
            response.error = 3;
            response.reason = "提交的代码不符合!";
        }finally {
            String json = mapper.writeValueAsString(response);
            resp.getWriter().write(json);
        }
    }

    private String mergeCode(String requestCode, String testCode) {
        int pos = requestCode.lastIndexOf("}");
        if (pos == -1){
            return null;
        }
        String subStr = requestCode.substring(0, pos);
        return subStr + testCode +"\n}";
    }

    private static String readBody(HttpServletRequest req) throws UnsupportedEncodingException {
        int contentLength = req.getContentLength();
        byte[] body = new byte[contentLength];
        try(InputStream inputStream = req.getInputStream()) {
            inputStream.read(body);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(body, "utf8");
    }
}
